package org.zpmis.domain.mail.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.zpmis.domain.mail.model.AttachMailMessageParam;
import org.zpmis.domain.mail.model.SimpleMailMessageParam;
import org.zpmis.domain.mail.model.TemplateMailMessageParam;
import org.zpmis.domain.mail.service.MailService;
import org.zpmis.utils.ByteToInputStreamUtil;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.io.InputStream;
import java.util.Date;
import java.util.Map;

@Slf4j
@Service
public class MailServiceImpl implements MailService {

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private TemplateEngine templateEngine;

    @Value("${spring.mail.username}")
    private String fromEmail;

    /**
     *  发送普通文本邮件
     */
    @Override
    public boolean sendSimpleMail(SimpleMailMessageParam messageParam) throws Exception {
        try {
            log.info("[MailServiceImpl]--ToEmial:{},CcEmail:{},BccEmail:{},Subject:{},Text:{}", messageParam.getToEmial(),messageParam.getCcEmail(),messageParam.getBccEmail(),messageParam.getSubject(),messageParam.getText());
            // 构建一个邮件对象
            SimpleMailMessage message = new SimpleMailMessage();
            // 设置邮件主题
            message.setSubject(messageParam.getSubject());
            // 设置邮件发送者，这个跟application.yml中设置的要一致
            message.setFrom(fromEmail);
            // 设置邮件接收者，可以有多个接收者，中间用逗号隔开，以下类似
            // message.setTo("10*****16@qq.com","12****32*qq.com");
            message.setTo(messageParam.getToEmial());
            if(!StringUtils.isEmpty(messageParam.getCcEmail())){
                // 设置邮件抄送人，可以有多个抄送人
                message.setCc(messageParam.getCcEmail());
            }
            if(!StringUtils.isEmpty(messageParam.getBccEmail())){
                // 设置隐秘抄送人，可以有多个
                message.setBcc(messageParam.getBccEmail());
            }
            // 设置邮件发送日期
            message.setSentDate(new Date());
            // 设置邮件的正文
            message.setText(messageParam.getText());
            // 发送邮件
            javaMailSender.send(message);
            return true;
        } catch (MailException e) {
            log.error("[MailServiceImpl]--sendAttachInputStreamMail--->Exception:",e);
            return false;
        }
    }


    /**
     * 发送普通文本并且带附件的邮件
     * @throws Exception
     */
    @Override
    public boolean sendAttachInputStreamMail(AttachMailMessageParam messageParam) throws Exception {
        log.info("[MailServiceImpl]--ToEmial:{},CcEmail:{},BccEmail:{},Subject:{},Text:{}", messageParam.getToEmial(),messageParam.getCcEmail(),messageParam.getBccEmail(),messageParam.getSubject(),messageParam.getText());
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            // true表示构建一个可以带附件的邮件对象
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);

            helper.setSubject(messageParam.getSubject());
            helper.setFrom(fromEmail);
            helper.setTo(messageParam.getToEmial());
            if(!StringUtils.isEmpty(messageParam.getCcEmail())){
                helper.setCc(messageParam.getCcEmail());
            }
            if(!StringUtils.isEmpty(messageParam.getBccEmail())){
                helper.setBcc(messageParam.getBccEmail());
            }
            helper.setSentDate(new Date());
            helper.setText(messageParam.getText());
            Map<String,byte[]> bytes = messageParam.getBytes();
            if(bytes != null && !bytes.isEmpty()){
                for (String key : bytes.keySet()) {
                    InputStream inputStream = ByteToInputStreamUtil.byte2Input(bytes.get(key));
                    // 第一个参数是自定义的名称，后缀需要加上，第二个参数是文件
                    helper.addAttachment(key,new ByteArrayResource(IOUtils.toByteArray(inputStream)));
                }
            }
            Map<String, File> files = messageParam.getFiles();
            if(files != null && !files.isEmpty()){
                for (String key : files.keySet()) {
                    // 第一个参数是自定义的名称，后缀需要加上，第二个参数是文件
                    helper.addAttachment(key,files.get(key));
                }
            }
            javaMailSender.send(mimeMessage);
            return true;
        } catch (MessagingException e) {
            log.error("[MailServiceImpl]--sendAttachInputStreamMail--->Exception:",e);
            return false;
        } catch (MailException e) {
            log.error("[MailServiceImpl]--sendAttachInputStreamMail--->Exception:",e);
            return false;
        }
    }

    /**
     *发送模板邮件. 支持附件或者不带附件都可以
     * @return
     * @throws Exception
     */
    @Override
    public boolean sendTemplateMail(TemplateMailMessageParam messageParam) throws Exception {
        log.info("[MailServiceImpl]--ToEmial:{},CcEmail:{},BccEmail:{},Subject:{},TemplateName:{}", messageParam.getToEmial(),messageParam.getCcEmail(),messageParam.getBccEmail(),messageParam.getSubject(),messageParam.getTemplateName());
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setSubject(messageParam.getSubject());
            helper.setFrom(fromEmail);
            helper.setTo(messageParam.getToEmial());
            if(!StringUtils.isEmpty(messageParam.getCcEmail())){
                helper.setCc(messageParam.getCcEmail());
            }
            if(!StringUtils.isEmpty(messageParam.getBccEmail())){
                helper.setBcc(messageParam.getBccEmail());
            }
            helper.setSentDate(new Date());
            // 这里引入的是Template的Context
            Context context = new Context();
            // 设置模板中的变量
            if(messageParam.getMap() != null && !messageParam.getMap().isEmpty())
            for (String key : messageParam.getMap().keySet()) {
                context.setVariable(key,messageParam.getMap().get(key));
            }
            // 第一个参数为模板的名称
            String process = templateEngine.process(messageParam.getTemplateName(), context);
            // 第二个参数true表示这是一个html文本
            helper.setText(process,true);
            //设置附件信息
            Map<String,byte[]> bytes = messageParam.getBytes();
            if(bytes != null && !bytes.isEmpty()){
                for (String key : bytes.keySet()) {
                    InputStream inputStream = ByteToInputStreamUtil.byte2Input(bytes.get(key));
                    // 第一个参数是自定义的名称，后缀需要加上，第二个参数是文件
                    helper.addAttachment(key,new ByteArrayResource(IOUtils.toByteArray(inputStream)));
                }
            }
            javaMailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("[MailServiceImpl]--sendAttachInputStreamMail--->Exception:",e);
            return false;
        } catch (MailException e) {
            log.error("[MailServiceImpl]--sendAttachInputStreamMail--->Exception:",e);
            return false;
        }
        return true;
    }
}
